package com.mes.schedule.mm;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.log4j.Logger;

/**
 *
 * <p>Title: MES</p>
 * <p>Description: ����ִ��ϵͳ</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: BUAA 720</p>
 * @author DHuang&XHuang
 * @version 1.0
 */

/**************************************************************************************
 *A common class to connect database and excute database operation.
 *Note: variable preStmt must be initialized before operation excution.You can invoke
 *prepareStatement(String sql) method to do it. preStmt is public,you can directly operate on it.
 *test/TestDBHandler.java������ʹ�õ�ʵ��
 * ************************************************************************************
 *author@DHuang&XHuang
 */

public class DBHandler {

  public static Logger logger = Logger.getLogger(DBHandler.class.getName());
  private Connection conn = null;
  public PreparedStatement stmt = null;
  private ResultSet rs = null;
  private String sql = null;

  //���ڵ��ô洢����
  public CallableStatement callableStmt = null;

  /**
   * ���캯��
   */
  public DBHandler() {
  }

  /**
   * ȡ�ö�kd���ݿ����ӵķ���
   * @return conn
   */
  public Connection getConn() throws SQLException,NamingException{
    if(conn == null){
      createConn();
    }
    return conn;
  }

  public void createConn() throws SQLException,NamingException{
    try {
      InitialContext ctx = new InitialContext();
      DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/mm");
      conn = ds.getConnection();
      //logger.info("���ݿ����ӳɹ�");
    }
    catch (SQLException e) {
      logger.info(
          "___________________DBHandler construct error_________________");
      e.printStackTrace();
      close();
      throw e;
    }
  }

  /**
   * ����PreparedStatement
   * @param sql String
   */
  public void createPreparedStatement(String sql) throws SQLException,NamingException {
    if(conn == null){
      createConn();
    }
    try {
      stmt = conn.prepareStatement(sql);
    }
    catch (SQLException e) {
      logger.info(
          "______________________DBHandler make preparedStatement error__________________");
      e.printStackTrace();
      close();
      throw e;
    }
  }

  /**
   * �õ�PreparedStatement�������ⲿ����
   * @param sql String
   * @return PreparedStatement
   */
  public PreparedStatement getPreparedStatement(String sql) throws SQLException,NamingException{
    if(this.sql == null || stmt == null || !sql.equals(this.sql)){
      createPreparedStatement(sql);
    }
    return stmt;
  }

  /**
   * ���Ѿ����ɵ�PreparedStatementִ�в�ѯ���ResultSet
   * @return ResultSet
   */
  public ResultSet getResultSet() throws SQLException,NamingException{
    try {
      rs = stmt.executeQuery();
      return rs;
    }
    catch (SQLException e) {
      logger.info(
          "_______________________DBHandler getResultSet error________________________");
      e.printStackTrace();
      close();
      throw e;
    }
  }

  /**
   * ֱ����sql�����ResultSet���������ȴ������Ӻ�PreparedStatement��
   * @return ResultSet
   */
  public ResultSet getResultSet(String sql) throws SQLException,NamingException{
    try {
      rs = getPreparedStatement(sql).executeQuery();
      return rs;
    }
    catch (SQLException e) {
      logger.info(
          "_______________________DBHandler getResultSet error________________________");
      e.printStackTrace();
      close();
      throw e;
    }
  }

  /**
   * ���Ѿ����ɵ�PreparedStatementִ��Update�޸Ĳ������޷��أ�����������Ϲر����Ӻ��αꡣ
   * ������insert,update,delete��sql���
   */
  public void executeUpdate() throws SQLException{
    try {
      stmt.executeUpdate();
    }
    catch (SQLException e) {
      logger.info(
          "_____________________DBHandler update error___________________");
      e.printStackTrace();
      close();
      throw e;
    }
  }

  /**
   * ���ֳ�������update()�����¼�������࣬���Ǳ�����executeUpdate()
   */
  public void update() throws SQLException{
    executeUpdate();
  }

  /**
   * ���Ѿ����ɵ�PreparedStatementִ��Delete��Insert����,�޷��أ�����������Ϲر����Ӻ��αꡣ
   * ���������е�sql���
   */
  public void execute() throws SQLException{
    try {
      stmt.execute();
    }
    catch (SQLException e) {
      logger.info("_____________________________DBHandler direct execute error__________________________");
      e.printStackTrace();
      close();
      throw e;
    }
  }

  /**
   * �ر����ݿ�����
   * @throws SQLException
   */
  public void close() {
    try {
      if (rs != null) {
        rs.close();
        //logger.info("�ѹر����ݼ�");
      }
      if (stmt != null) {
        stmt.close();
        //logger.info("�ѹر��α�");
      }
      if (conn != null || (conn != null && !conn.isClosed())) {
        conn.close();
        //logger.info("�ѹر����ݿ�����");
      }
    }
    catch (SQLException e) {
      e.printStackTrace();
    }
  }

  /**
   * ֻ�رյ��α꣬���ر�����
   */
  public void closeStmt() {
    try {
      if (rs != null) {
        rs.close();
        //logger.info("�ѹر����ݼ�");
      }
      if (stmt != null) {
        stmt.close();
        //logger.info("�ѹر��α�");
      }
    }
    catch (SQLException e) {
      e.printStackTrace();
    }

  }

  /**
   * �������ڴ洢���̵�CallableStatement
   * @param sql String
   */
  public void createCallableStatement(String sql) throws SQLException{
    try {
      callableStmt = conn.prepareCall(sql);
    }
    catch (SQLException e) {
      e.printStackTrace();
      close();
      throw e;
    }
  }

  /**
   * ִ�д洢����
   */
  public void executeCallableStatement() throws SQLException{
    try {
      callableStmt.execute();
    }
    catch (SQLException ex) {
      ex.printStackTrace();
      close();
      throw ex;
    }
  }

  public void closeCallableStatement() throws SQLException{
      if (callableStmt != null) {
        callableStmt.close();
        //logger.info("�ѹر��α�");
      }
      if (conn != null || (conn != null && !conn.isClosed())) {
        conn.close();
        //logger.info("�ѹر����ݿ�����");
      }
  }

  /**
   * ʹ�õ�������ο�test/TestDBHandler.java
   */
}
